package com.zrrd.yunchmall.gateway.filter;

import com.zrrd.yunchmall.gateway.client.AuthServiceClient;
import com.zrrd.yunchmall.user.entity.Admin;
import com.zrrd.yunchmall.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 在网关中实现统一的权限认证
 * 针对每个请求头或请求参数中的token令牌进行有效性验证，如果有效就完成后续的路由操作，否则直接返回 401 错误（无访问权限）
 */
// 第一步：声明一个Filter类，实现GlobalFilter接口
@Service //第三步：将这个类注入Spring的bean容器
@ConfigurationProperties("auth-filter")
@SuppressWarnings("all")
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;

    //保证我们自定义的过滤器位于整个过滤器链路的最前端
    @Override
    public int getOrder() {
        return 1;
    }
    // 不需要进行鉴权的请求路径集合（excludes包括的路径直接放行）
    private List<String> excludes;
    public List<String> getExcludes() {
        return excludes;
    }
    public void setExcludes(List<String> excludes) {
        this.excludes = excludes;
    }

    @Autowired
    private AuthServiceClient authService;
    // 第二步：重写filter方法
//    @Value("${auth-filter.enabled}")
    private boolean enabled; //设置一个基于配置文件的开关，true：过滤器工作，false：过滤器不工作
    public boolean isEnabled() {
        return enabled;
    }
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    @Override
    @SuppressWarnings("all")
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        System.out.println("进来了！");
        // 当enabled == false，直接跳过当前过滤器
        if (!enabled) return chain.filter(exchange);
        // 请求路径 /shop-user/user/login
        String uri = exchange.getRequest().getURI().getPath();
        // 如果是包含在放行路径集合里的URI直接通过鉴权环节
        if (excludes.contains(uri)) {
            return chain.filter(exchange);
        }
        // Authorization这个请求头中要包含jwt token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        // 1.没找到token 2.token过期了 3.token无效（被伪造的）4.token令牌在redis中未找到
        String key = "LOGIN_TOKEN_" + token.substring(token.lastIndexOf(".") + 1);
        Admin admin = JwtUtil.parseAdminToken(token.substring(7));
        boolean hasToken = redisTemplate.hasKey(key);
        if (token == null
                || JwtUtil.parseAdminToken(token.substring(7)) == null
                || !redisTemplate.hasKey(key)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 401
            return exchange.getResponse().setComplete();//响应结束，方法将中止
        } else {
            return chain.filter(exchange);
        }
//        return null;
    }

}
